package com.ydl.shopping.thread;

import com.ydl.shopping.core.entity.TaskInfo;
import com.ydl.shopping.core.enums.TaskStatusEnum;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.Date;

/**
 * 异步任务监控
 *
 * 主要是利用了spring的AOP面向切面，在异步方法的执行前和执行后进行监控，判断任务状态，并记录任务信息。
 */
@Component
@Aspect
public class AsyncTaskMonitor {
    @Resource
    private AsyncTaskManager manager;

    private static final Logger log = LoggerFactory.getLogger(AsyncTaskMonitor.class);

    @Around("execution(* com.ydl.shopping.async.AsyncTaskExecutor.*(..))")
    public void taskHandle(ProceedingJoinPoint joinPoint) {
        // 获取taskID
        String taskId = joinPoint.getArgs()[1].toString();
        // 获取任务信息
        TaskInfo taskInfo = manager.getTaskInfo(taskId);
        log.info("AsyncTaskMonitor正在监控异步任务:{}", taskId);
        taskInfo.setStatus(TaskStatusEnum.RUNNING);
        manager.setTaskInfo(taskInfo);
        TaskStatusEnum status;
        try {
            joinPoint.proceed();
            status = TaskStatusEnum.SUCCESS;
        } catch (Throwable throwable) {
            status = TaskStatusEnum.FAILED;
            log.error("AsyncTaskMonitor:异步任务{}失败 错误信息:{}", taskId, throwable.getMessage());
        }
        taskInfo.setEndTime(new Date());
        taskInfo.setStatus(status);
        taskInfo.setTotalTime();
        manager.setTaskInfo(taskInfo);
    }
}
